#include <vector>
#include <string>
#include <fstream>
#include <iostream>

using namespace std;

/*
 * 创建两个具有 26 个元素的数组 begin 和 end，其中，每个数组的初始值都是 -1。
 * 其中：
 * beg[0] 表示第一次遇到牛 A 的位置
 * beg[1] 表示第一次遇到牛 B 的位置
 * ...
 * 以此类推
 * 
 * end[0] 表示第二次遇到牛 A 的位置
 * end[1] 表示第二次遇到牛 B 的位置
 * ...
 * 以此类推
 * 那么，对于 John 记录的路径 ABCCAB 来说；
 * beg 和 end 中记录的值是这样的：
 * 
 * beg {0, 1, 2}
 * end {4, 5, 3}
 * 
 * 问题一、如何根据 John 的路径设置 beg 和 end
 * 问题二、如何根据 beg 和 end 数组的值推测出交叉
 */

int main(int argc, char const *argv[])
{
  /* code */
  vector<int> begin(26, -1);
  vector<int> end(26, -1);

  // 处理输入和输出
  string path;

  ifstream ifs("CrossTheRoad.in");
  ifs >> path;

  // 遍历 path，检查每一头牛进出的情况
  for (int i = 0; i < path.size(); ++i) {
    char cow = path[i]; // char 'A', 'B', 'C'
    // 怎么能够把 'A' -> 位置 0
    // 怎么能够把 'B' -> 位置 1
    // 计算每一个字母到 'A' 的距离
    int pos = cow - 'A'; // cow 在 begin 和 end 这两个数组中对应的位置

    if (begin[pos] == -1) {
      // 在 path 上，第一次遇到 cow
      begin[pos] = i;
    }
    else {
      // 在 path 上，第二次遇到 cow
      end[pos] = i;
    }
  }

  // 我们就记录下了 path 中每一头牛第一次和第二次发现它们的位置
  // 根据这些位置信息判断交叉点
  int result = 0;

  // beg
  // [xx, xx, xx, xx, xx, ..., xx]
  // end
  // [xx, xx, xx, xx, xx, ..., xx]
  for (int i = 0; i < 26; ++i) {
    // 遍历 begin 和 end，逐个检查每一个位置
    for (int j = 0; j < 26; ++j) {
      // i = 0
      // j = 0, 1, 2, 3, ..., 25
      // 判断的是 位置 i 的奶牛是不是和位置 j 的奶牛有交叉
      if (begin[i] < begin[j] && begin[j] < end[i] && end[i] < end[j]) {
        ++result;
      }
    }
  }

  ofstream ofs("CrossTheRoad.out");
  ofs << result;

  return 0;
}
